package com.ivan.toolkit.swing;



import java.util.Collection;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import com.google.common.collect.Lists;

public class RowTableModel<T> extends AbstractTableModel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1687346625456327278L;
	
	/**
	 * ColumnContent for RowTableModel
	 * @author lingdm
	 *
	 */
	public static interface ColumnContent<T> {
		public String getName();
		public abstract Object getValue(T data);
	}

	/**
	 * ColumnContents
	 */
	private List<ColumnContent<T>> columnContents = Lists.newLinkedList();
	
	/**
	 * Rows
	 */
	protected List<T> rows = Lists.newLinkedList();
	
	/**
	 * constructor
	 * @param rowList
	 */
	public RowTableModel() {
		super();
		this.rows = Lists.newLinkedList();
		//this.columnContents = columnContents;
		if(rows == null) {
			throw new IllegalArgumentException("Null row list supplied.");
		}
		if(columnContents == null) {
			throw new IllegalArgumentException("Null columnContent list supplied.");
		}
	}
	
	public void addColumnContent(ColumnContent<T> content) {
		if(columnContents.add(content)) {
			this.fireTableStructureChanged();
		}
	}
	
	public void removeColumnContent(ColumnContent<T> content) {
		if(columnContents.remove(content)) {
			this.fireTableStructureChanged();
		}
	}

	@Override
	public int getRowCount() {
		return rows.size();
	}

	@Override
	public int getColumnCount() {
		return columnContents.size();
	}

	@Override
	public String getColumnName(int column) {
		try {
			ColumnContent<T> content = columnContents.get(column);
			return content.getName();
		} catch(ArrayIndexOutOfBoundsException e) {
			return null;
		}
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		try {
			ColumnContent<T> content = columnContents.get(columnIndex);
			return content.getValue(getRow(rowIndex));
		} catch(ArrayIndexOutOfBoundsException e) {
			return null;
		}
	}
	
	public T getRow(int rowIndex) {
		try {
			return rows.get(rowIndex);
		} catch (IndexOutOfBoundsException e) {
			return null;
		}
	}
	
	public List<T> getRows() {
		return Lists.newArrayList(rows);
	}
	
	public void appendRow(T row) {
		int index = rows.size();
		if(rows.add(row)) {
			this.fireTableRowsInserted(index, index);
		}
	}
	
	public void appendRows(Collection<T> rows) {
		int index = rows.size();
		if(this.rows.addAll(rows)) {
			this.fireTableRowsInserted(index, index + rows.size());
		}
	}
	
	public void removeRow(T row) {
		int index = rows.indexOf(row);
		if(index != -1) {
			rows.remove(index);
			this.fireTableRowsDeleted(index, index);
		}
	}
	
	public void removeAllRows() {
		rows.clear();
		this.fireTableDataChanged();
	}
	
	public void updateRow(T row) {
		int index = rows.indexOf(row);
		if(index != -1) {
			this.fireTableRowsUpdated(index, index);
		}
	}
	
	public void updateRow() {
		this.fireTableDataChanged();
	}

}
